
package com.hlkj.pay.app.merchant.ext.impl.easypay.handler;
/*
 * Hlpay-Plus aggregate payment system.
 * Copyright (c) 2024-2025 Hlpay Team Copyright has the right of final interpretation.
 */

import cn.hutool.core.date.DatePattern;
import com.fasterxml.jackson.core.type.TypeReference;
import com.hlkj.framework.common.pojo.CommonResult;
import com.hlkj.framework.common.util.id.IdUtils;
import com.hlkj.framework.common.util.json.JsonUtils;
import com.hlkj.framework.http.template.OkHttpTemplate;
import com.hlkj.pay.app.merchant.ext.dto.profit.ChannelProfitAccountBindContext;
import com.hlkj.pay.app.merchant.ext.dto.profit.ChannelProfitAccountContext;
import com.hlkj.pay.app.merchant.ext.impl.MerchantAccessUploadFile;
import com.hlkj.pay.app.merchant.ext.impl.easypay.constant.EasyPayConstant;
import com.hlkj.pay.app.merchant.ext.impl.easypay.dto.EasyPayConfig;
import com.hlkj.pay.app.merchant.ext.impl.easypay.dto.EasypayAppChannelParams;
import com.hlkj.pay.app.merchant.ext.impl.easypay.dto.req.EasyPayReqDto;
import com.hlkj.pay.app.merchant.ext.impl.easypay.dto.req.EasyPayReqHeader;
import com.hlkj.pay.app.merchant.ext.impl.easypay.dto.res.EasePayCommonRes;
import com.hlkj.pay.app.merchant.ext.impl.easypay.dto.res.EasyPayRespStateInfo;
import com.hlkj.pay.app.merchant.ext.impl.easypay.dto.res.account.EasePayFundAccountCommonRes;
import com.hlkj.pay.app.merchant.ext.impl.easypay.dto.res.account.EasyPayAccountRes;
import com.hlkj.pay.app.merchant.ext.impl.easypay.dto.res.account.EasyPayPictureRes;
import com.hlkj.pay.app.merchant.ext.impl.easypay.utils.EasyPaySignUtil;
import com.hlkj.pay.common.MerchantResultCode;
import com.hlkj.pay.dto.merchant.fund.MerchantFundAccountBindDto;
import com.hlkj.pay.dto.merchant.fund.MerchantFundAccountDto;
import com.hlkj.pay.enums.MerchantEnum;
import com.hlkj.pay.infrastructure.model.merchant.MerchantCardDO;
import com.hlkj.pay.infrastructure.model.merchant.MerchantCertInfoDO;
import com.hlkj.pay.infrastructure.model.merchant.MerchantLicenseDO;
import com.hlkj.pay.infrastructure.model.merchant.fund.MerchantFundAccountDO;
import com.hlkj.pay.infrastructure.model.pay.PayChannelRequestDO;
import com.hlkj.pay.util.DateUtils;
import com.hlkj.pay.util.FileUtils;
import com.hlkj.pay.util.ImageUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.*;

/**
 * @author HlpayTeam
 * @date 2024/10/16 9:10
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class EasyPayMerchantAccountHandler extends EasyPayMerchantCommonParamsHandle {

    private final OkHttpTemplate okHttpTemplate;

    /**
     * @param channelProfitAccountContext
     */
    public void submitProfitAccount(ChannelProfitAccountContext channelProfitAccountContext) {
        log.info("易生渠道提交分账账号 请求参数:{}", JsonUtils.toJsonString(channelProfitAccountContext.getMerchantFundAccountDto()));
        CommonResult<EasyPayConfig> easyPayConfigCommonResult = channelConfig(channelProfitAccountContext.getProviderChannelConfig());
        // 配置转换
        if (!easyPayConfigCommonResult.isSuccess()) {
            channelProfitAccountContext.setRemark(easyPayConfigCommonResult.getMsg());
            channelProfitAccountContext.setProcessStatus(Boolean.FALSE);
            return;
        }
        EasyPayConfig easyPayConfig = easyPayConfigCommonResult.getData();
        // 1. 数据初始化
        try {
            addProcessFileId(channelProfitAccountContext, easyPayConfig);
            if (!channelProfitAccountContext.isProcessStatus()) {
                return;
            }
            CommonResult<Void> paramsCommonResult = checkAccountParams(channelProfitAccountContext);
            // 参数组装
            if (!paramsCommonResult.isSuccess()) {
                channelProfitAccountContext.setProcessStatus(Boolean.FALSE);
                channelProfitAccountContext.setRemark(paramsCommonResult.getMsg());
                log.error("易生开户参数校验失败 message: {}", paramsCommonResult.getMsg());
                return;
            }
            Map<String, Object> params = merchantAccountParams(channelProfitAccountContext);
            EasyPayReqDto easyPayReqDto = easyPayReqDto(easyPayConfig, params);
            String requestBody = JsonUtils.toJsonString(easyPayReqDto);
            log.info("易生新增分账账号 请求参数:{}", requestBody);
            String url = yqtDomain(channelProfitAccountContext.isTest()) + EasyPayConstant.NONMEMBER_ADD;
            PayChannelRequestDO payChannelRequestDO = payChannelRequestDO(url, easyPayReqDto);
            channelProfitAccountContext.setPayChannelRequest(payChannelRequestDO);
            payChannelRequestDO.setResponse(payChannelRequestDO.getResponse());
            log.info("易生新增分账账号 返回参数:{}", payChannelRequestDO.getResponse());
            EasePayCommonRes<EasyPayAccountRes> easePayFundAccountCommonRes = JsonUtils.parseObject(payChannelRequestDO.getResponse(), new TypeReference<>() {
            });
            if (!easePayFundAccountCommonRes.success()) {
                channelProfitAccountContext.setProcessStatus(Boolean.FALSE);
                channelProfitAccountContext.setRemark(easePayFundAccountCommonRes.getRspHeader().getRspInfo());
                return;
            }
            EasyPayAccountRes rspBody = easePayFundAccountCommonRes.getRspBody();
            EasyPayRespStateInfo respStateInfo = rspBody.getRespStateInfo();
            if(respStateInfo!=null){
                if (!respStateInfo.success()) {
                    channelProfitAccountContext.setProcessStatus(Boolean.FALSE);
                    channelProfitAccountContext.setRemark(respStateInfo.getRespDesc());
                    return;
                }
            }else if(!rspBody.success()) {
                channelProfitAccountContext.setProcessStatus(Boolean.FALSE);
                channelProfitAccountContext.setRemark(rspBody.getRetMsg());
                return;
            }
            channelProfitAccountContext.setAccountNo(rspBody.getMchtCode());
        }
        catch (Exception e) {
            e.printStackTrace();
            log.error("易生新增分账账号,失败信息 message: {}", e.getMessage());
            channelProfitAccountContext.setRemark("易生新增分账账号,失败信息" + (StringUtils.hasText(e.getMessage()) ? e.getMessage() : " 数据解析异常"));
            channelProfitAccountContext.setProcessStatus(Boolean.FALSE);
        }
    }

    public void updateProfitAccount(ChannelProfitAccountContext channelProfitAccountContext) {
        log.info("易生渠道修改分账账号 请求参数:{}", JsonUtils.toJsonString(channelProfitAccountContext.getMerchantFundAccountDto()));
        CommonResult<EasyPayConfig> easyPayConfigCommonResult = channelConfig(channelProfitAccountContext.getProviderChannelConfig());
        // 配置转换
        if (!easyPayConfigCommonResult.isSuccess()) {
            channelProfitAccountContext.setRemark(easyPayConfigCommonResult.getMsg());
            channelProfitAccountContext.setProcessStatus(Boolean.FALSE);
            return;
        }
        EasyPayConfig easyPayConfig = easyPayConfigCommonResult.getData();
        // 1. 数据初始化
        try {
            CommonResult<Void> paramsCommonResult = checkAccountParams(channelProfitAccountContext);
            // 参数组装
            if (!paramsCommonResult.isSuccess()) {
                channelProfitAccountContext.setProcessStatus(Boolean.FALSE);
                channelProfitAccountContext.setRemark(paramsCommonResult.getMsg());
                log.error("易生修改参数校验失败 message: {}", paramsCommonResult.getMsg());
                return;
            }
            Map<String, Object> params = updateAccountParams(channelProfitAccountContext);
            EasyPayReqDto easyPayReqDto = easyPayReqDto(easyPayConfig, params);
            String requestBody = JsonUtils.toJsonString(easyPayReqDto);
            log.info("易生修改分账账号 请求参数:{}", requestBody);
            String url = yqtDomain(channelProfitAccountContext.isTest()) + EasyPayConstant.NONMEMBER_UPDATE;
            PayChannelRequestDO payChannelRequestDO = payChannelRequestDO(url, easyPayReqDto);
            channelProfitAccountContext.setPayChannelRequest(payChannelRequestDO);
            payChannelRequestDO.setResponse(payChannelRequestDO.getResponse());
            log.info("易生修改分账账号 返回参数:{}", payChannelRequestDO.getResponse());
            EasePayFundAccountCommonRes<EasyPayAccountRes> easePayFundAccountCommonRes = JsonUtils.parseObject(payChannelRequestDO.getResponse(), new TypeReference<>() {
            });
            if (!easePayFundAccountCommonRes.success()) {
                channelProfitAccountContext.setProcessStatus(Boolean.FALSE);
                channelProfitAccountContext.setRemark(easePayFundAccountCommonRes.getRspHeader().getRspInfo());
                return;
            }
            EasyPayAccountRes rspBody = easePayFundAccountCommonRes.getRspBody();
            EasyPayRespStateInfo respStateInfo = rspBody.getRespStateInfo();
            if(respStateInfo!=null){
                if (!respStateInfo.success()) {
                    channelProfitAccountContext.setProcessStatus(Boolean.FALSE);
                    channelProfitAccountContext.setRemark(respStateInfo.getRespDesc());
                    return;
                }
            }else if(!rspBody.success()) {
                channelProfitAccountContext.setProcessStatus(Boolean.FALSE);
                channelProfitAccountContext.setRemark(rspBody.getRetMsg());
                return;
            }
            channelProfitAccountContext.setAccountNo(rspBody.getMchtCode());
        }
        catch (Exception e) {
            e.printStackTrace();
            log.error("易生修改分账账号,失败信息 message: {}", e.getMessage());
            channelProfitAccountContext.setRemark("易生修改分账账号,失败信息" + (StringUtils.hasText(e.getMessage()) ? e.getMessage() : " 数据解析异常"));
            channelProfitAccountContext.setProcessStatus(Boolean.FALSE);
        }
    }

    public void bindProfitAccount(ChannelProfitAccountBindContext channelMerchantAccessContext) {
        MerchantFundAccountBindDto merchantFundAccountBindDto = channelMerchantAccessContext.getMerchantFundAccountBindDto();
        log.info("易生渠道提交分账账号绑定 请求参数:{}", JsonUtils.toJsonString(merchantFundAccountBindDto));
        CommonResult<EasyPayConfig> easyPayConfigCommonResult = channelConfig(channelMerchantAccessContext.getProviderChannelConfig());
        // 配置转换
        if (!easyPayConfigCommonResult.isSuccess()) {
            channelMerchantAccessContext.setRemark(easyPayConfigCommonResult.getMsg());
            channelMerchantAccessContext.setProcessStatus(Boolean.FALSE);
            return;
        }
        EasyPayConfig easyPayConfig = easyPayConfigCommonResult.getData();
        // 1. 数据初始化

        EasypayAppChannelParams easypayAppChannelParams = easyPayAppChannelParams(channelMerchantAccessContext.getMerchantAppChannelDO());
        if(!StringUtils.hasText(easypayAppChannelParams.getCustomerNo())){
            channelMerchantAccessContext.setProcessStatus(Boolean.FALSE);
            channelMerchantAccessContext.setRemark("通道商户号为空");
            return;
        }
        try {
            Map<String, Object> reqBody = new HashMap<>();
            Map<String, Object> applyInfo = new HashMap<>();
            reqBody.put("applyInfo", applyInfo);
            reqBody.put("applyNo", IdUtils.getSnowflakeNextIdStr());
            reqBody.put("mchtCode", easypayAppChannelParams.getCustomerNo());
            reqBody.put("customerCode", merchantFundAccountBindDto.getMerchantFundAccountBindDO().getAccountNo());
            EasyPayReqDto easyPayReqDto = easyPayReqDto(easyPayConfig, reqBody);
//            easyPayReqDto.getReqHeader().setReqType("2");
            log.info("易生分账账号绑定请求参数:{}", JsonUtils.toJsonString(easyPayReqDto));
            String url = yqtDomain(channelMerchantAccessContext.isTest()) + EasyPayConstant.NONMEMBER_BIND;
            PayChannelRequestDO payChannelRequestDO = payChannelRequestDO(url, easyPayReqDto);
            channelMerchantAccessContext.setPayChannelRequest(payChannelRequestDO);
            log.info("易生分账账号绑定返回参数:{}", payChannelRequestDO.getResponse());
            EasePayFundAccountCommonRes<EasyPayAccountRes> easePayFundAccountCommonRes = JsonUtils.parseObject(payChannelRequestDO.getResponse(),
                    new TypeReference<EasePayFundAccountCommonRes<EasyPayAccountRes>>() {
                    });
            if (!easePayFundAccountCommonRes.success()) {
                channelMerchantAccessContext.setProcessStatus(Boolean.FALSE);
                channelMerchantAccessContext.setRemark(easePayFundAccountCommonRes.getRspHeader().getRspInfo());
                return;
            }
            EasyPayAccountRes rspBody = easePayFundAccountCommonRes.getRspBody();
            EasyPayRespStateInfo respStateInfo = rspBody.getRespStateInfo();
            if(respStateInfo!=null){
                if (!respStateInfo.success()) {
                    channelMerchantAccessContext.setProcessStatus(Boolean.FALSE);
                    channelMerchantAccessContext.setRemark(respStateInfo.getRespDesc());
                    return;
                }
            }else if(!rspBody.success()) {
                channelMerchantAccessContext.setProcessStatus(Boolean.FALSE);
                channelMerchantAccessContext.setRemark(rspBody.getRetMsg());
                return;
            }
        }
        catch (Exception e) {
            e.printStackTrace();
            log.error("易生分账账号绑定,失败信息 message: {}", e.getMessage());
            channelMerchantAccessContext.setRemark("易生分账账号绑定,失败信息" + (StringUtils.hasText(e.getMessage()) ? e.getMessage() : " 数据解析异常"));
            channelMerchantAccessContext.setProcessStatus(Boolean.FALSE);
        }
    }

    public void unBindProfitAccount(ChannelProfitAccountBindContext channelMerchantAccessContext) {
        MerchantFundAccountBindDto merchantFundAccountBindDto = channelMerchantAccessContext.getMerchantFundAccountBindDto();
        log.info("易生渠道分账账号解除绑定 请求参数:{}", JsonUtils.toJsonString(merchantFundAccountBindDto));
        CommonResult<EasyPayConfig> easyPayConfigCommonResult = channelConfig(channelMerchantAccessContext.getProviderChannelConfig());
        // 配置转换
        if (!easyPayConfigCommonResult.isSuccess()) {
            channelMerchantAccessContext.setRemark(easyPayConfigCommonResult.getMsg());
            channelMerchantAccessContext.setProcessStatus(Boolean.FALSE);
            return;
        }
        EasyPayConfig easyPayConfig = easyPayConfigCommonResult.getData();
        // 1. 数据初始化
        EasypayAppChannelParams easypayAppChannelParams = easyPayAppChannelParams(channelMerchantAccessContext.getMerchantAppChannelDO());
        if(!StringUtils.hasText(easypayAppChannelParams.getCustomerNo())){
            channelMerchantAccessContext.setProcessStatus(Boolean.FALSE);
            channelMerchantAccessContext.setRemark("通道商户号为空");
            return;
        }
        try {
            Map<String, Object> reqBody = new HashMap<>();
            Map<String, Object> applyInfo = new HashMap<>();
            reqBody.put("applyInfo", applyInfo);
            reqBody.put("applyNo", IdUtils.getSnowflakeNextIdStr());
            reqBody.put("mchtCode", easypayAppChannelParams.getCustomerNo());
            reqBody.put("customerCode", merchantFundAccountBindDto.getMerchantFundAccountBindDO().getAccountNo());
            EasyPayReqDto easyPayReqDto = easyPayReqDto(easyPayConfig, reqBody);
//            easyPayReqDto.getReqHeader().setReqType("2");
            log.info("易生分账账号解除绑请求参数:{}", JsonUtils.toJsonString(easyPayReqDto));
            String url = yqtDomain(channelMerchantAccessContext.isTest()) + EasyPayConstant.NONMEMBER_UNBIND;
            PayChannelRequestDO payChannelRequestDO = payChannelRequestDO(url, easyPayReqDto);
            channelMerchantAccessContext.setPayChannelRequest(payChannelRequestDO);
            log.info("易生分账账号解除绑返回参数:{}", payChannelRequestDO.getResponse());
            EasePayFundAccountCommonRes<EasyPayAccountRes> easePayFundAccountCommonRes = JsonUtils.parseObject(payChannelRequestDO.getResponse(), new TypeReference<>() {
            });
            if (!easePayFundAccountCommonRes.success()) {
                channelMerchantAccessContext.setProcessStatus(Boolean.FALSE);
                channelMerchantAccessContext.setRemark(easePayFundAccountCommonRes.getRspHeader().getRspInfo());
                return;
            }
            EasyPayAccountRes rspBody = easePayFundAccountCommonRes.getRspBody();
            EasyPayRespStateInfo respStateInfo = rspBody.getRespStateInfo();
            if(respStateInfo!=null){
                if (!respStateInfo.success()) {
                    channelMerchantAccessContext.setProcessStatus(Boolean.FALSE);
                    channelMerchantAccessContext.setRemark(respStateInfo.getRespDesc());
                    return;
                }
            }else if(!rspBody.success()) {
                channelMerchantAccessContext.setProcessStatus(Boolean.FALSE);
                channelMerchantAccessContext.setRemark(rspBody.getRetMsg());
                return;
            }
        }
        catch (Exception e) {
            e.printStackTrace();
            log.error("易生分账账号解除绑,失败信息 message: {}", e.getMessage());
            channelMerchantAccessContext.setRemark("易生分账账号解除绑,失败信息" + (StringUtils.hasText(e.getMessage()) ? e.getMessage() : " 数据解析异常"));
            channelMerchantAccessContext.setProcessStatus(Boolean.FALSE);
        }
    }

    public void queryAccountBindList(ChannelProfitAccountBindContext channelProfitAccountBindContext) {
        MerchantFundAccountBindDto merchantFundAccountBindDto = channelProfitAccountBindContext.getMerchantFundAccountBindDto();
        log.info("易生渠道分账账号绑定查询 请求参数:{}", JsonUtils.toJsonString(merchantFundAccountBindDto));
        CommonResult<EasyPayConfig> easyPayConfigCommonResult = channelConfig(channelProfitAccountBindContext.getProviderChannelConfig());
        // 配置转换
        if (!easyPayConfigCommonResult.isSuccess()) {
            channelProfitAccountBindContext.setRemark(easyPayConfigCommonResult.getMsg());
            channelProfitAccountBindContext.setProcessStatus(Boolean.FALSE);
            return;
        }
        EasyPayConfig easyPayConfig = easyPayConfigCommonResult.getData();
        // 1. 数据初始化
        EasypayAppChannelParams easypayAppChannelParams = easyPayAppChannelParams(channelProfitAccountBindContext.getMerchantAppChannelDO());
        try {
            Map<String, Object> reqBody = new HashMap<>();
            reqBody.put("mchtCode", easypayAppChannelParams.getCustomerNo());
            // reqBody.put("customerCode", "KK0000000000109");
            EasyPayReqDto easyPayReqDto = easyPayReqDto(easyPayConfig, reqBody);
            log.info("易生分账账号绑定查询请求参数:{}", JsonUtils.toJsonString(easyPayReqDto));
            String url = yqtDomain(channelProfitAccountBindContext.isTest()) + EasyPayConstant.NONMEMBER_QUERY_LEDGER;
            PayChannelRequestDO payChannelRequestDO = payChannelRequestDO(url, easyPayReqDto);
            channelProfitAccountBindContext.setPayChannelRequest(payChannelRequestDO);
            log.info("易生分账账号绑定查询返回参数:{}", payChannelRequestDO.getResponse());
        }
        catch (Exception e) {
            e.printStackTrace();
            log.error("易生分账账号解除绑,失败信息 message: {}", e.getMessage());
            channelProfitAccountBindContext.setRemark("易生分账账号解除绑,失败信息" + (StringUtils.hasText(e.getMessage()) ? e.getMessage() : " 数据解析异常"));
            channelProfitAccountBindContext.setProcessStatus(Boolean.FALSE);
        }
    }
    private CommonResult<Void> checkAccountParams(ChannelProfitAccountContext channelMerchantAccessContext) {
        MerchantFundAccountDto merchantFundAccountDto = channelMerchantAccessContext.getMerchantFundAccountDto();
        MerchantCardDO merchantFundCard = merchantFundAccountDto.getMerchantFundCard();
        switch (MerchantEnum.SETTLE_CYCLE.from(merchantFundCard.getSettleCycle())) {
            case D0:
            case D1:
            case T1:
                break;
            default:
                return CommonResult.error(1, "易生支付分账当前结算周期不支持");
        }
        return CommonResult.success();
    }

    /**
     * @param channelMerchantAccessContext
     * @return
     */
    private Map<String, Object> merchantAccountParams(ChannelProfitAccountContext channelMerchantAccessContext) {
        MerchantFundAccountDto merchantFundAccountDto = channelMerchantAccessContext.getMerchantFundAccountDto();
        MerchantFundAccountDO merchantFundAccount = merchantFundAccountDto.getMerchantFundAccount();
        MerchantCertInfoDO merchantFundLegal = merchantFundAccountDto.getMerchantFundLegal();
        MerchantLicenseDO merchantFundLicense = merchantFundAccountDto.getMerchantFundLicense();
        MerchantCertInfoDO merchantFundContact = merchantFundAccountDto.getMerchantFundContact();
        MerchantCardDO merchantFundCard = merchantFundAccountDto.getMerchantFundCard();
        Map<String, Object> params = new HashMap<>();
        Map<String, Object> applyInfo = new HashMap<>();
        applyInfo.put("applyNo", merchantFundAccount.getRequestId());
        params.put("applyInfo", applyInfo);

        Map<String, Object> merchantInfo = new HashMap<>();
        merchantInfo.put("mchtBzType", "1");
        merchantInfo.put("mchtSubType", "2");
        if (merchantFundLicense != null) {
            merchantInfo.put("mchtName", merchantFundLicense.getName());
            merchantInfo.put("mchtMode", "B");
        }
        else {
            merchantInfo.put("mchtName", merchantFundLegal.getName());
            merchantInfo.put("mchtMode", "C");
        }
        if (merchantFundContact != null) {
            merchantInfo.put("agentMobile", merchantFundContact.getPhone());
            merchantInfo.put("agentPerson", merchantFundContact.getName());
        }
        params.put("merchantInfo", merchantInfo);
        Map<String, Object> licInfoInfo = new HashMap<>();
        licInfoInfo.put("legalIdAddr", merchantFundLegal.getAddress());
        licInfoInfo.put("legalIdNo", merchantFundLegal.getCertNo());
        licInfoInfo.put("legalIdType", getCerType(merchantFundLegal.getCertType()));
        licInfoInfo.put("legalIdValidityEnd", date(merchantFundLegal.getCertEndDate()));
        licInfoInfo.put("legalIdValidityStart", date(merchantFundLegal.getCertBeginDate()));
        licInfoInfo.put("legalMobile", merchantFundLegal.getPhone());
        licInfoInfo.put("legalName", merchantFundLegal.getName());
        if (merchantFundLicense != null) {
            licInfoInfo.put("licenseAddr", merchantFundLicense.getAddress());
            licInfoInfo.put("licenseName", merchantFundLicense.getName());
            licInfoInfo.put("licenseNo", merchantFundLicense.getLicenseCode());
            licInfoInfo.put("licenseNoValidityEnd", date(merchantFundLicense.getLicenseEndDate()));
            licInfoInfo.put("licenseNoValidityStart", date(merchantFundLicense.getLicenseBeginDate()));
        }
        params.put("licInfoInfo", licInfoInfo);
        Map<String, Object> payAccInfo = new HashMap<>();
        payAccInfo.put("bankName", merchantFundCard.getBankName());
        payAccInfo.put("bankNo", merchantFundCard.getBranchCode());
        if (MerchantEnum.CARD_TYPE.CORPORATE_ACCOUNT.getCode().equals(merchantFundCard.getType())) {
            payAccInfo.put("acctType", "05");
        }
        else {
            payAccInfo.put("acctType", "00");
        }
        payAccInfo.put("accIdNo", merchantFundLegal.getCertNo());
        payAccInfo.put("accIdType", getCerType(merchantFundLegal.getCertType()));
        payAccInfo.put("bankcardName", merchantFundCard.getName());
        payAccInfo.put("bankcardNo", merchantFundCard.getCardNo());
        payAccInfo.put("accMobile", merchantFundCard.getCardPhone());
        params.put("payAccInfo", payAccInfo);
        Map<String, Object> sceneFunctionList = new HashMap<>();
        switch (MerchantEnum.SETTLE_CYCLE.from(merchantFundCard.getSettleCycle())) {
            case D0:
                sceneFunctionList.put("businessSceneCode", "Settle");
                sceneFunctionList.put("payAbilityCode", "RealAcct");
                sceneFunctionList.put("payMethodCode", "Default");
                sceneFunctionList.put("tag", "I");
                break;
            case D1:
                sceneFunctionList.put("businessSceneCode", "Settle");
                sceneFunctionList.put("payAbilityCode", "D1Acct");
                sceneFunctionList.put("payMethodCode", "Default");
                break;
            case T1:
                sceneFunctionList.put("businessSceneCode", "Settle");
                sceneFunctionList.put("payAbilityCode", "T1Acct");
                sceneFunctionList.put("payMethodCode", "Default");
                break;
        }
        params.put("sceneFunctionList", new ArrayList<>() {

            {
                add(sceneFunctionList);
            }
        });
        List<MerchantAccessUploadFile> merchantAccessUploadFiles = channelMerchantAccessContext.getMerchantAccessUploadFiles();
        List<Map<String, Object>> pictureList = new ArrayList<>();

        merchantAccessUploadFiles.stream().forEach(merchantAccessUploadFile -> {
            Map<String, Object> picture = new HashMap<>();
            picture.put("picType", merchantAccessUploadFile.getFileKey());
            picture.put("picPath", merchantAccessUploadFile.getFileId());
            pictureList.add(picture);
        });
        params.put("pictureList", pictureList);
        return params;
    }

    /**
     * @param channelMerchantAccessContext
     * @return
     */
    private Map<String, Object> updateAccountParams(ChannelProfitAccountContext channelMerchantAccessContext) {
        MerchantFundAccountDto merchantFundAccountDto = channelMerchantAccessContext.getMerchantFundAccountDto();
        MerchantFundAccountDO merchantFundAccount = merchantFundAccountDto.getMerchantFundAccount();
        // MerchantCertInfoDO merchantFundLegal =
        // merchantFundAccountDto.getMerchantFundLegal();
        // MerchantLicenseDO merchantFundLicense =
        // merchantFundAccountDto.getMerchantFundLicense();
        // MerchantCertInfoDO merchantFundContact =
        // merchantFundAccountDto.getMerchantFundContact();
        MerchantCardDO merchantFundCard = merchantFundAccountDto.getMerchantFundCard();
        MerchantCardDO oldMerchantFundCard = merchantFundAccountDto.getOldMerchantFundCard();
        Map<String, Object> params = new HashMap<>();
        HashMap<String, Object> applyInfo = new HashMap<>();
        applyInfo.put("mchtCode", merchantFundAccount.getAccountNo());
        applyInfo.put("applyNo", IdUtils.getSnowflakeNextIdStr());
        params.put("applyInfo", applyInfo);

        Map<String, Object> merchantInfo = new HashMap<>();
        merchantInfo.put("mchtBzType", "1");
        // if (merchantFundLicense != null) {
        // merchantInfo.put("mchtName", merchantFundLicense.getName());
        // merchantInfo.put("mchtMode", "B");
        // }
        // else {
        // merchantInfo.put("mchtName", merchantFundLegal.getName());
        // merchantInfo.put("mchtMode", "C");
        // }
        // if (merchantFundContact != null) {
        // merchantInfo.put("agentMobile", merchantFundContact.getPhone());
        // merchantInfo.put("agentPerson", merchantFundContact.getName());
        // }
        // params.put("merchantInfo", merchantInfo);
        // Map<String, Object> licInfoInfo = new HashMap<>();
        // licInfoInfo.put("legalIdAddr", merchantFundLegal.getAddress());
        // licInfoInfo.put("legalIdNo", merchantFundLegal.getCertNo());
        // licInfoInfo.put("legalIdType", getCerType(merchantFundLegal.getCertType()));
        // licInfoInfo.put("legalIdValidityEnd",
        // date(merchantFundLegal.getCertEndDate()));
        // licInfoInfo.put("legalIdValidityStart",
        // date(merchantFundLegal.getCertBeginDate()));
        // licInfoInfo.put("legalMobile", merchantFundLegal.getPhone());
        // licInfoInfo.put("legalName", merchantFundLegal.getName());
        // if (merchantFundLicense != null) {
        // licInfoInfo.put("licenseAddr", merchantFundLicense.getAddress());
        // licInfoInfo.put("licenseName", merchantFundLicense.getName());
        // licInfoInfo.put("licenseNo", merchantFundLicense.getLicenseCode());
        // licInfoInfo.put("licenseNoValidityEnd",
        // date(merchantFundLicense.getLicenseEndDate()));
        // licInfoInfo.put("licenseNoValidityStart",
        // date(merchantFundLicense.getLicenseBeginDate()));
        // }
        // params.put("licInfoInfo", licInfoInfo);
        Map<String, Object> payAccInfo = new HashMap<>();
        payAccInfo.put("bankName", merchantFundCard.getBankName());
        payAccInfo.put("bankNo", merchantFundCard.getBranchCode());
        if (MerchantEnum.CARD_TYPE.CORPORATE_ACCOUNT.getCode().equals(merchantFundCard.getType())) {
            payAccInfo.put("acctType", "05");
        }
        else {
            payAccInfo.put("acctType", "00");
            // payAccInfo.put("accIdNo", merchantFundLegal.getCertNo());
            // payAccInfo.put("accIdType", getCerType(merchantFundLegal.getCertType()));
        }
        payAccInfo.put("bankcardName", merchantFundCard.getName());
        payAccInfo.put("bankcardNo", merchantFundCard.getCardNo());
        payAccInfo.put("accMobile", merchantFundCard.getCardPhone());
        params.put("payAccInfo", payAccInfo);

         Map<String, Object> addFunctionList = new HashMap<>();
         switch (MerchantEnum.SETTLE_CYCLE.from(merchantFundCard.getSettleCycle())) {
             case D0:
                 addFunctionList.put("businessSceneCode", "Settle");
                 addFunctionList.put("payAbilityCode", "RealAcct");
                 addFunctionList.put("payMethodCode", "Default");
                 addFunctionList.put("tag", "I");
                 break;
             case D1:
                 addFunctionList.put("businessSceneCode", "Settle");
                 addFunctionList.put("payAbilityCode", "D1Acct");
                 addFunctionList.put("payMethodCode", "Default");
                 addFunctionList.put("tag", "I");
                 break;
             case T1:
                 addFunctionList.put("businessSceneCode", "Settle");
                 addFunctionList.put("payAbilityCode", "T1Acct");
                 addFunctionList.put("payMethodCode", "Default");
                 addFunctionList.put("tag", "I");
                 break;
         }
         Map<String, Object> delFunctionList = new HashMap<>();
         switch (MerchantEnum.SETTLE_CYCLE.from(oldMerchantFundCard.getSettleCycle())) {
             case D0:
                 delFunctionList.put("businessSceneCode", "Settle");
                 delFunctionList.put("payAbilityCode", "RealAcct");
                 delFunctionList.put("payMethodCode", "Default");
                 delFunctionList.put("tag", "D");
                 break;
             case D1:
                 delFunctionList.put("businessSceneCode", "Settle");
                 delFunctionList.put("payAbilityCode", "D1Acct");
                 delFunctionList.put("payMethodCode", "Default");
                 delFunctionList.put("tag", "D");
                 break;
             case T1:
                 delFunctionList.put("businessSceneCode", "Settle");
                 delFunctionList.put("payAbilityCode", "T1Acct");
                 delFunctionList.put("payMethodCode", "Default");
                 delFunctionList.put("tag", "D");
                 break;
         }
         params.put("sceneFunctionList", new ArrayList<>() {

             {
                 add(addFunctionList);
                 add(delFunctionList);
             }
         });
        return params;
    }

    /**
     * 新增文件参数转换
     *
     * @param channelMerchantAccessContext
     */
    public void addProcessFileId(ChannelProfitAccountContext channelMerchantAccessContext, EasyPayConfig easyPayConfig) {
        MerchantFundAccountDto merchantAccessDto = channelMerchantAccessContext.getMerchantFundAccountDto();
        MerchantLicenseDO merchantAccessLicense = merchantAccessDto.getMerchantFundLicense();
        MerchantCertInfoDO merchantAccessLegal = merchantAccessDto.getMerchantFundLegal();
        // 配置转换
        boolean test = channelMerchantAccessContext.isTest();
        Map<String, String> fileMap = new HashMap<>();
        // if (beforeMerchantAccessRequestDO != null &&
        // StringUtils.hasText(beforeMerchantAccessRequestDO.getFileParams())) {
        // fileMap =
        // JsonUtils.parseObject(beforeMerchantAccessRequestDO.getFileParams(),
        // Map.class);
        // }
        try {
            // 01,,法人身份证人像面
            // 02,,法人身份证国徽面
            // 03,,商户联系人身份证人像面
            // 04,,商户联系人身份证国徽面
            // 05,,营业执照
            // 06,,收银台
            // 07,,内部环境照
            // 08,,营业场所门头照
            // 09,,门牌号
            // 10,,协议
            // 11,,商户登记表正面
            // 12,,商户登记表反面
            // 13,,开户许可证
            // 14,,银行卡
            // 15,,清算授权书
            // 16,,定位照（非必填）
            // 17,,手持身份证招聘（非必填）
            // 18,,收款人身份证人像面
            // 19,,收款人身份证国徽面
            // 20,,手持清算授权书
            // 21,,特殊行业执照
            // 22,,变更单
            // 23,,其他照片
            // 24,,其他照片
            // 96,,协议01
            // 97,,协议02
            // 98,,协议03
            // 99,,协议04
            List<MerchantAccessUploadFile> merchantAccessUploadFiles = new ArrayList<>();
            if (merchantAccessLicense != null) {
                merchantAccessUploadFiles.add(MerchantAccessUploadFile.builder().fileKey("05").fileUrl(merchantAccessLicense.getLicenseUrl()).build());
            }
            else {
                merchantAccessUploadFiles.add(MerchantAccessUploadFile.builder().fileKey("01").fileUrl(merchantAccessLegal.getCertFrontUrl()).build());
                merchantAccessUploadFiles.add(MerchantAccessUploadFile.builder().fileKey("02").fileUrl(merchantAccessLegal.getCertBackUrl()).build());
            }
            for (MerchantAccessUploadFile merchantAccessUploadFile : merchantAccessUploadFiles) {
                CommonResult<Void> f07 = fileUploadProcess(fileMap, easyPayConfig, merchantAccessUploadFile, test);
                if (!f07.isSuccess()) {
                    channelMerchantAccessContext.setProcessStatus(Boolean.FALSE);
                    channelMerchantAccessContext.setRemark(f07.getMsg());
                    return;
                }
            }
            channelMerchantAccessContext.setMerchantAccessUploadFiles(merchantAccessUploadFiles);
        }
        catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
        finally {
        }
    }

    public CommonResult<Void> fileUploadProcess(Map<String, String> fileMap, EasyPayConfig easyPayConfig, MerchantAccessUploadFile merchantAccessUploadFile, boolean test) {
        if (!StringUtils.hasText(merchantAccessUploadFile.getFileUrl())) {
            return CommonResult.success();
        }
        String fileKey = merchantAccessUploadFile.getFileUrl().hashCode() + "_" + merchantAccessUploadFile.getFileKey();
        String fileId = fileMap.get(fileKey);
        if (StringUtils.hasText(fileId)) {
            log.info("easyPay文件映射获取成功 fileUrl:{},fileId:{}", merchantAccessUploadFile.getFileUrl(), fileId);
            merchantAccessUploadFile.setFileId(fileId);
            return CommonResult.success();
        }
        log.info("easyPay文件映射获取未成功 fileType:{}, fileUrl:{}", test, merchantAccessUploadFile.getFileUrl());
        CommonResult<Void> f371 = fileUpload(merchantAccessUploadFile, easyPayConfig, test);
        if (f371.isSuccess()) {
            fileMap.put(fileKey, merchantAccessUploadFile.getFileId());
        }
        return f371;
    }

    /**
     * 文件上传
     *
     * @param merchantAccessUploadFile
     * @param easyPayConfig
     * @return
     * @throws Exception
     */
    public CommonResult<Void> fileUpload(MerchantAccessUploadFile merchantAccessUploadFile, EasyPayConfig easyPayConfig, boolean test) {
        if (!file(merchantAccessUploadFile.getFileUrl())) {
            log.info("文件格式错误 跳过文件上传:fileUrl:{},test:{}", merchantAccessUploadFile.getFileUrl(), test);
            return CommonResult.success();
        }
        try {
            Map<String, Object> bodyMap = new HashMap<>();
            bodyMap.put("fileName", ImageUtils.getImageNameFromUrl(merchantAccessUploadFile.getFileUrl()));
            bodyMap.put("fileText", Base64.getEncoder().encodeToString(FileUtils.fileBytes(merchantAccessUploadFile.getFileUrl())));
            bodyMap.put("orgCode", easyPayConfig.getOrgCode());
            EasyPayReqDto easyPayReqDto = easyPayReqDto(easyPayConfig, bodyMap);
            log.info("易生上传图片请求参数:{}", JsonUtils.toJsonString(bodyMap));
            String url = yqtDomain(test) + EasyPayConstant.PICTURE_UPLOAD;
            String response = okHttpTemplate.post(url, JsonUtils.toJsonString(easyPayReqDto), null);
            log.info("易生上传图片返回参数:{}", response);
            EasePayFundAccountCommonRes<EasyPayPictureRes> easePayFundAccountCommonRes = JsonUtils.parseObject(response, new TypeReference<EasePayFundAccountCommonRes<EasyPayPictureRes>>() {
            });
            EasyPayPictureRes rspBody = easePayFundAccountCommonRes.getRspBody();
            if (!rspBody.success()) {
                return CommonResult.error(MerchantResultCode.MERCHANT_ACCESS_FILE_ERROR.getCode(),
                        rspBody == null ? easePayFundAccountCommonRes.getRspHeader().getRspInfo() : rspBody.getRetMsg());
            }
            merchantAccessUploadFile.setFileId(rspBody.getFileId());
            return CommonResult.success();
        }
        catch (Exception e) {
            e.printStackTrace();
            log.error("签名异常:{}", e.getMessage());
            return CommonResult.error(MerchantResultCode.MERCHANT_ACCESS_FILE_ERROR.getCode(), e.getMessage());
        }
    }

    public String yqtDomain(boolean test) {
        return test ? EasyPayConstant.PAY_ORDER_DOMAIN_TEST : EasyPayConstant.PAY_ORDER_DOMAIN_PROD;
    }

    EasyPayReqDto easyPayReqDto(EasyPayConfig easyPayConfig, Map<String, Object> params) throws Exception {
        EasyPayReqDto easyPayReqDto = new EasyPayReqDto();
        EasyPayReqHeader header = new EasyPayReqHeader(easyPayConfig.getAcctReqId(), DateUtils.getDateString(DatePattern.PURE_DATETIME_PATTERN));
        header.setReqType("2");
        easyPayReqDto.setReqHeader(header);
        easyPayReqDto.setReqBody(params);
        easyPayReqDto.setReqSign(EasyPaySignUtil.sign(easyPayReqDto, easyPayConfig.getRsaPrivateKey()));
        return easyPayReqDto;
    }

    PayChannelRequestDO payChannelRequestDO(String url, Object params) throws Exception {
        PayChannelRequestDO payChannelRequestDO = new PayChannelRequestDO();
        payChannelRequestDO.setRequestUrl(url);
        String requestBody = JsonUtils.toJsonString(params);
        payChannelRequestDO.setRequestParams(requestBody);
        String post = okHttpTemplate.post(url, requestBody, null);
        payChannelRequestDO.setResponse(post);
        return payChannelRequestDO;
    }

}
